package com.tianji.promotion.service.impl;

import com.tianji.promotion.constants.PromotionConstants;
import com.tianji.promotion.domain.po.Coupon;
import com.tianji.promotion.domain.po.ExchangeCode;
import com.tianji.promotion.mapper.ExchangeCodeMapper;
import com.tianji.promotion.service.IExchangeCodeService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tianji.promotion.util.CodeUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 兑换码 服务实现类
 * </p>
 *
 * @author liuchun
 * @since 2024-10-23
 */
@Service
@Slf4j
public class ExchangeCodeServiceImpl extends ServiceImpl<ExchangeCodeMapper, ExchangeCode> implements IExchangeCodeService {

    @Autowired
    private StringRedisTemplate redisTemplate;

    //异步生成兑换码
    @Override
    @Async("generateExchangeCodeExecutor")
    public void asyncCreateExchangeCode(Coupon c) {
        log.info("发放兑换码线程，{}", Thread.currentThread().getName());
        //总数量
        Integer totalNum = c.getTotalNum();
        Long maxSerialNum = redisTemplate.opsForValue().increment(PromotionConstants.COUPON_CODE_SERIAL_KEY, totalNum);
        if (maxSerialNum == null) {
            return;
        }
        List<ExchangeCode> exchangeCodeList = new ArrayList<>(totalNum);
        int beginNum = maxSerialNum.intValue() - totalNum + 1;
        for(int i = beginNum; i <= maxSerialNum; i++) {
            String code = CodeUtil.generateCode(i, c.getId());
            ExchangeCode exchangeCode = new ExchangeCode();
            exchangeCode.setId(i);//兑换码
            exchangeCode.setCode(code);
            exchangeCode.setExchangeTargetId(c.getId());
            exchangeCode.setExpiredTime(c.getIssueEndTime());//兑换码 兑换的截止时间，即优惠券截止发放的时间
            exchangeCodeList.add(exchangeCode);
        }
        //保存兑换码
        saveBatch(exchangeCodeList);

        //写入Redis缓存
        //redisTemplate.opsForZSet().add(Coupon);
    }

    //检查兑换码是否已经使用
    @Override
    public boolean checkIsExchanged(long serialNum, boolean b) {
        String key = PromotionConstants.COUPON_CODE_MAP_KEY;
        Boolean res = redisTemplate.opsForValue().setBit(key, serialNum, b);
        //不为空且为true，则表示已经兑换了
        return res !=null && res;
    }
}
